﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HeresyManager
{
    [Serializable]
    public class Divination : IMinMaxRole
    {
        public String Name { get; private set; }
        Func<Character, IEnumerator<Comunication.Comunicator>> accire;
        Action<Character> deAccire;

        public int MinRole { get; set; }
        public int MaxRole { get; set; }

        public Divination(String name, int minRole, int maxRole) : this(name, minRole, maxRole, (c) => { return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator(); }, (c) => { }) { }


        public Divination(String name, int minRole, int maxRole, Func<Character, IEnumerator<Comunication.Comunicator>> accire, Action<Character> deAccire)
        {
            this.accire = accire;
            this.deAccire = deAccire;
            Name = name;
            this.MinRole = minRole;
            this.MaxRole = maxRole;
        }

        public virtual IEnumerator<Comunication.Comunicator> Accire(Character c) { return accire(c); }
        public virtual void DeAccire(Character c) { deAccire(c); }

        public override string ToString()
        {
            return Name;
        }

        public static Divination[] Divinations
        {
            get
            {
                return new Divination[] { 
                    new DivinationMutationWithoutCoruption()   ,
                    new Divination(  "Only the insane have strength enough to prosper. Only those who prosper may judge what is sane.",2,3,c=>{c.InsanityPoints+=2;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.InsanityPoints-=2),
                    new Divination(  "Sins hidden in the heart turn all to decay.",4,7,c=>{c.CorruptionPoints+=3;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.CorruptionPoints-=3),
                    new Divination(  "Innocence is an illusion.",8,8,c=>{c.CorruptionPoints+=1;c.InsanityPoints+=1;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>{c.CorruptionPoints-=1;c.InsanityPoints-=1;}),
                    new Divination(  "Dark dreams lie upon the heart.",9,11,c=>{c.CorruptionPoints+=2;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.CorruptionPoints-=2),
                    new Divination(  "The pain of the bullet is ecstasy compared to damnation.",12,15,c=>{c.T+=1;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.T-=1),
                    new Divination(  "Kill the alien before it can speak its lies.",16,18,c=>{c.Ag+=2;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.Ag-=2),
                    new Divination(  "Truth is subjective.",19,21,c=>{c.Int+=3;c.CorruptionPoints+=3;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>{c.CorruptionPoints-=3;c.Int-=3;}),
                    new Divination(  "Know the mutant; kill the mutant.",22,26,c=>{c.Per+=2;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.Per-=2),
                    new Divination(  "Even a man who has nothing can still offer his life.",27,30,c=>{c.S+=2;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.S-=2),
                    new Ifajobisworthdoingitisworthdyingfor(),            
                    new Divination(  "Only in death does duty end.",34,38,c=>{c.TotalWounds+=1;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.TotalWounds-=1),
                    new Divination(  "A mind without purpose will wander in dark places.",39,42,c=>{c.TotalFatepoints+=1;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.TotalFatepoints-=1),
                    new Divination(  "There are no civilians in the battle for survival.",43,46,c=>{c.T+=2;c.TotalWounds+=1;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>{c.T-=2;c.TotalWounds-=1;}),
                    new Divination(  "Violence solves everything.",47,50,c=>{c.WS+=3;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.WS-=3),
                    new Divination(  "To war is human.",51,54,c=>{c.Ag+=3;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.Ag-=3),
                    new Divination(  "Die if you must, but not with your spirit broken.",55,58,c=>{c.Wp+=3;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.Wp-=3),
                    new Divination(  "The gun is mightier than the sword.",59,62,c=>{c.BS+=3;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.BS-=3),
                    new Divination(  "Be a boon to your brothers and bane to your enemies.",63,66,c=>{c.Fel+=3;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.Fel-=3),
                    new Divination(  "Men must die so that Man endures.",67,70,c=>{c.T+=3;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.T-=3),
                    new Divination(  "In the darkness, follow the light of Terra.",71,74,c=>{c.Wp+=3;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.Wp-=3),
                    new Divination(  "The only true fear is of dying with your duty not done.",75,79,c=>{c.TotalWounds+=2;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.TotalWounds-=2),
                    new Divination(  "Thought begets Heresy; Heresy begets Retribution.",80,85,c=>{c.S+=3;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.S-=3),
                    new Divination(  "The wise man learns from the deaths of others.",86,90,c=>{c.Int+=3;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.Int-=3),
                    new Divination(  "A suspicious mind is a healthy mind.",91,94,c=>{c.Per+=3;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>c.Per-=3),
                    new Divination(  "Trust in your fear.",95,97,c=>{c.Ag+=2;c.TotalFatepoints+=1;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>{c.Ag-=2;c.TotalFatepoints-=1;}),
                    new Divination(  "There is no substitute for zeal.",98,99,c=>{c.T+=2;c.Wp+=2;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>{c.Wp-=2;c.T-=2;}),
                    new Divination(  "Do not ask why you serve. Only ask how.",100,100,c=>{c.WS+=2;c.BS+=2;return new Comunication.Comunicator[0].AsEnumerable().GetEnumerator();},c=>{c.BS-=2;c.WS-=2;})


                };
            }
        }

        #region Functions that can not be lambda

        [Serializable]
        private class DivinationMutationWithoutCoruption : Divination
        {
            public DivinationMutationWithoutCoruption()
                : base("Mutation without, corruption within.", 1, 1)
            {
            }

            private Maligancy mal;

            public override void DeAccire(Character c)
            {
                c.RemoveMaligancy(mal);
            }

            public override IEnumerator<Comunication.Comunicator> Accire(Character c)
            {
                var en = new Comunication.ChooseOne<Maligancy>("Maligancy", Maligancy.Maligancies);
                while (en.SelectedValue == null)
                    yield return en;
                mal = en.SelectedValue;
                c.AddMaligancy(mal);

            }

        }

        [Serializable]
        private class Ifajobisworthdoingitisworthdyingfor : Divination
        {
            public Ifajobisworthdoingitisworthdyingfor()
                : base("If a job is worth doing it is worth dying for.", 31, 33)
            {
            }

            private Talents.Frenzy frenz;

            public override void DeAccire(Character c)
            {
                c.RemoveTalent(frenz, this);
            }

            public override IEnumerator<Comunication.Comunicator> Accire(Character c)
            {
                frenz = new Talents.Frenzy();
                return c.AddTalent(frenz, this);
            }

        }




        #endregion

    }
}
